---
title: "Reference: Express Adapter | Server"
description: "API reference for the @mastra/express server adapter."
---

import Steps from "@site/src/components/Steps";
import StepItem from "@site/src/components/StepItem";
import PropertiesTable from "@site/src/components/PropertiesTable";

# Express Adapter

The `@mastra/express` package provides a server adapter for running Mastra with [Express](https://expressjs.com).

:::info

For general adapter concepts (constructor options, initialization flow, etc.), see [Server Adapters](/docs/v1/server-db/server-adapters).

:::

## Installation

<Steps>

<StepItem>

Install the Express adapter and Express framework:

```bash copy
npm install @mastra/express express
```

</StepItem>

<StepItem>

Create your server file:

```typescript title="server.ts" copy showLineNumbers
import express from 'express';
import { MastraServer } from '@mastra/express';
import { mastra } from './mastra';

const app = express();
app.use(express.json()); // Required for body parsing

const server = new MastraServer({ app, mastra });
await server.init();

app.listen(4111, () => {
  console.log('Server running on port 4111');
});
```

</StepItem>

</Steps>

:::note

Express requires `express.json()` middleware for JSON body parsing. Add it before creating the `MastraServer`.

:::

## Full example

```typescript title="server.ts" copy showLineNumbers
import express from 'express';
import { MastraServer } from '@mastra/express';
import { mastra } from './mastra';

const app = express();
app.use(express.json());

const server = new MastraServer({
  app,
  mastra,
  prefix: '/api/v2',
  openapiPath: '/openapi.json',
  bodyLimitOptions: {
    maxSize: 10 * 1024 * 1024, // 10MB
    onError: (err) => ({ error: 'Payload too large', maxSize: '10MB' }),
  },
  streamOptions: { redact: true },
});

await server.init();

app.listen(4111);
```

## Constructor parameters

<PropertiesTable
  content={[
    {
      name: "app",
      type: "Application",
      description: "Express app instance",
      isOptional: false,
    },
    {
      name: "mastra",
      type: "Mastra",
      description: "Mastra instance",
      isOptional: false,
    },
    {
      name: "prefix",
      type: "string",
      description: "Route path prefix (e.g., `/api/v2`)",
      isOptional: true,
      defaultValue: "''",
    },
    {
      name: "openapiPath",
      type: "string",
      description: "Path to serve OpenAPI spec (e.g., `/openapi.json`)",
      isOptional: true,
    },
    {
      name: "bodyLimitOptions",
      type: "{ maxSize: number, onError: (err) => unknown }",
      description: "Request body size limits",
      isOptional: true,
    },
    {
      name: "streamOptions",
      type: "{ redact?: boolean }",
      description: "Stream redaction config. When true, redacts sensitive data from streams.",
      isOptional: true,
      defaultValue: "{ redact: true }",
    },
    {
      name: "customRouteAuthConfig",
      type: "Map<string, boolean>",
      description: "Per-route auth overrides. Keys are `METHOD:PATH` (e.g., `GET:/api/health`). Value `false` makes route public, `true` requires auth.",
      isOptional: true,
    },
  ]}
/>

## Differences from Hono

| Aspect | Express | Hono |
|--------|---------|------|
| Body parsing | Requires `express.json()` | Handled by framework |
| Context storage | `res.locals` | `c.get()` / `c.set()` |
| Middleware signature | `(req, res, next)` | `(c, next)` |
| Streaming | `res.write()` / `res.end()` | `stream()` helper |
| AbortSignal | Created from `req.on('close')` | `c.req.raw.signal` |

## Adding custom routes

Add routes directly to the Express app:

```typescript title="server.ts" copy showLineNumbers
const app = express();
app.use(express.json());

const server = new MastraServer({ app, mastra });

// Before init - runs before Mastra middleware
app.get('/early-health', (req, res) => res.json({ status: 'ok' }));

await server.init();

// After init - has access to Mastra context
app.get('/custom', (req, res) => {
  const mastraInstance = res.locals.mastra;
  res.json({ agents: Object.keys(mastraInstance.listAgents()) });
});

app.listen(4111);
```

:::tip

Routes added before `init()` run without Mastra context. Add routes after `init()` to access the Mastra instance and request context.

:::

## Accessing context

In Express middleware and routes, access Mastra context via `res.locals`:

```typescript copy showLineNumbers
app.get('/custom', (req, res) => {
  const mastra = res.locals.mastra;
  const requestContext = res.locals.requestContext;
  const abortSignal = res.locals.abortSignal;

  const agent = mastra.getAgent('myAgent');
  res.json({ agent: agent.name });
});
```

Available properties on `res.locals`:

| Key | Description |
|-----|-------------|
| `mastra` | Mastra instance |
| `requestContext` | Request context map |
| `abortSignal` | Request cancellation signal |
| `tools` | Available tools |
| `user` | Authenticated user (if auth configured) |

## Adding middleware

Add Express middleware before or after `init()`:

```typescript title="server.ts" copy showLineNumbers
const app = express();
app.use(express.json());

// Middleware before init
app.use((req, res, next) => {
  console.log(`${req.method} ${req.url}`);
  next();
});

const server = new MastraServer({ app, mastra });
await server.init();

// Middleware after init has access to Mastra context
app.use((req, res, next) => {
  const mastra = res.locals.mastra;
  // ...
  next();
});
```

## Manual initialization

For custom middleware ordering, call each method separately instead of `init()`. See [Server Adapters: Manual initialization](/docs/v1/server-db/server-adapters#manual-initialization) for details.

## Examples

- [Express Adapter](https://github.com/mastra-ai/mastra/tree/main/examples/server-express-adapter) - Basic Express server setup

## Related

- [Server Adapters](/docs/v1/server-db/server-adapters) - Shared adapter concepts
- [Hono Adapter](/reference/v1/server/hono-adapter) - Alternative adapter
- [MastraServer Reference](/reference/v1/server/mastra-server) - Full API reference
- [createRoute() Reference](/reference/v1/server/create-route) - Creating type-safe custom routes
